import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex); // 在Vue中使用vuex插件  

// 创建 store实例 => 存储公共状态 计算属性 方法
let store = new Vuex.Store({
  state: {  // state选项可以是对象,也可以是返回对象的函数 (参考vue->data)
    a: 1,
    b: 2,
    info:{
      name:"张三",
      age:18,
    }
  },
  getters: {
    // 类似vue中的计算属性 -> 依赖于state  
    //  函数中的第一参数: state -> 当前store实例中的state对象
    //  函数中的第二参数: getters -> 当前store实例中的getters对象
    doubleA: function (state) {
      return state.a * 2;
    },
    doubleB: function (state) {
      return state.b * 2;
    },
    doubleBoth: function (state, getters) { // 一个计算属性,可以依赖其他的计算属性
      // return (state.a+ state.b) * 2;
      return getters.doubleA + getters.doubleB;
    }

  },
  // 一般用来存储同步方法  
  mutations: { //  类似vue中的methods -> 依赖于state   (mutayions中的方法只能是同步的)
    //  函数中的第一参数: state -> 当前store实例中的state对象
    //  函数中的第二参数: payload(载荷)  方法被调用时可以接收一个实际参数被形参接收 
    addA: function (state) {
      state.a++;
    },
    addAN: function (state, payload) {
      console.log("addAN执行了", payload);
      state.a += payload;
    },
    addB: function (state) {
      state.b++;
    },
  },


  // 一般用来存储异步方法 (如果改变数据-> 还是需要调用mutations中的方法)
  // 方法调用完毕,默认返回Promise实例(pending), 如果异步函数执行过程中没有出错,等函数执行完毕,promise实例会变为已成功,函数的返回值就是作为Promise实例中存储的数据,如果函数执行过程中出现错误,Promise实例也会变为已失败状态

  // 结论:actions中方法调用完毕,默认返回Promise实例(pending), 如果函数的返回值是普通数据,直接链式将数据向后传递,如果函数的返回值是Promise实例(处理异步操作),可以等Promise实例状态改变之后再向后传递
  
  // 可以知道 action 什么时候结束,更重要的是，可以组合多个 action，以处理更加复杂的异步流程
  actions: {
    // 异步方法: 函数 ->  注意actions中不能修改数据, 如果需要修改数据,必须先在mutations中定义同步方法修改数据,在调用mutations中的方法
    // 函数中的第一参数: context -> 和store实例有相同属性和方法的新对象   {state,getters,commit,dispatch}
    //  函数中的第二参数: payload(载荷)  actions方法被调用时可以接收一个实际参数被形参接收 

    // context = {state:store.state,getters:store.getters, commit:store.commit, dispatch:store.dispatch}

    // addA_Async(context, payload) {
    //   console.log("addA_Async触发了:context", context);  //{state,getters,commit,dispatch}
    //   console.log("addA_Async触发了:payload", payload);

    //   return 100;   // 
    // },
    addA_Async(context, payload) {
      console.log("addA_Async触发了:context", context);  //{state,getters,commit,dispatch}
      console.log("addA_Async触发了:payload", payload);

      return new Promise(function (resolve) {  // 可以知道异步操作是否结束
        setTimeout(() => {

          context.commit("addA");
          resolve();
        }, 1000)
      })
    },
    addB_Async(context, payload) {
      console.log("addB_Async触发了:context", context);  //{state,getters,commit,dispatch}
      console.log("addB_Async触发了:payload", payload);
      return new Promise(function (resolve) {
        setTimeout(() => {
          context.commit("addB");
          resolve();
        }, 1000)
      })
    },
    addAN_Async(context, payload) {
      console.log("addAN_Async触发了:context", context);  //{state,getters,commit,dispatch}
      console.log("addAN_Async触发了:payload", payload);
      setTimeout(() => {
        // 如何调用mutations中的方法!!!!!
        context.commit("addAN", payload);
      }, 1000)
    },
    addBoth_Async(context, payload) {
      console.log("addBoth_Async触发了:context", context);  //{state,getters,commit,dispatch}
      console.log("addBoth_Async触发了:payload", payload);
      // 在actions方法中调用另一个异步方法
      context.dispatch("addA_Async");
      context.dispatch("addB_Async");
    },
    test: async function (context, payload) {
      // context = {state,getters,commit,dispatch}

      let { state, getters, commit, dispatch } = context;
      state
      getters
      commit
      dispatch
      payload


      // var res = commit("addA");
      // console.log("同步方法的返回值",res);  // undefined

      var res = dispatch("addA_Async");  // 返回Promise实例  1s变为fulfilled 
      
      // 链式接收 -> 麻烦
      res.then(data => {
        console.log("addA_Async执行完毕", data);
        return  dispatch("addB_Async");
      }).then(data => {
        console.log("addB_Async执行完毕", data);
      }).catch(err => {
        console.log("addA_Async执行过程出错", err);
      })



      // async await 接收 -> 
      // var res = await dispatch("addA_Async");  // 返回Promise实例  => 默认pending, 1s变为fulfilled 
      // await dispatch("addB_Async"); 


    }
  },
  modules: {

  }
})

export default store;
